package com.dems.core.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * Created by tinyylh on 2019/03/31.
 * 数据工厂
 */
@Component
@Slf4j
public class DataFactory {

//    @Autowired
//    private RedisTemplate redisTemplate;


    /**
     * 随机数默认位数  **不能修改
     */
    private final static int ranLen = 6;

    /**
     * 获取进程/线程的默认位数  **不能修改
     */
    private final static int ptLen = 3;

    /**
     * 时间长度  **不能修改
     */
    private final static int dateTimeLen = 14;

    private static final int SIZE = 6;
    private static final String SYMBOL = "*";

    public static final BigDecimal DEFAULT_PRICE = BigDecimal.valueOf(39.90);

    public static final BigDecimal XL003_PRICE = BigDecimal.valueOf(49.90);

    /**
     * 获取唯一id （固定长度20位）
     *
     * @param key redis key
     * @return
     */
    public String getUID(String key) {
        int sufLength = ranLen;
        return redisIdByDate(key, sufLength);
    }

    /**
     * 获取唯一id （17-22位之间）
     *
     * @param key
     * @param length id总长度
     * @return
     */
    public String getUIDByLen1(String key, int length) {
        if (length < 16 || length > 22) {
            return null;
        }
        length = length - dateTimeLen;
        return redisIdByDate(key, length);
    }




    /**
     * 获取唯一id 时间+自增序列
     *
     * @param key       redis key
     * @param sufLength 自增的位数
     * @return
     */
    public String redisIdByDate(String key, int sufLength) {
        //获取时间戳
        String dateTime = LoanassistConstants.sdf_time1.format(new Date());
        String incr = "";
        String suffex = String.valueOf(System.nanoTime()).substring(6, 13);
//        try {
//            Long timestamp = (Long) redisTemplate.execute(RedisServerCommands::time);
//            dateTime = LoanassistConstants.sdf_time1.format(new Date(timestamp));
//        } catch (Exception e) {
//            log.error("未获取到REDIS时间,请及时解决...", e);
//        }
        //获取redis自增
//        try {
//            incr = incrId(key, sufLength);
//        } catch (Exception e) {
//            incr = String.valueOf(random(sufLength));
//            log.error("key=" + key, "", "获取REDIS自增ID时异常,请及时解决...", e);
//        }
        log.info(String.format("KEY[%s],时间[%s]+自增ID[%s]=UID[%s]", key, dateTime, incr, dateTime + incr));
        return dateTime + incr + suffex;
    }


    /**
     * 根据random拼接唯一ID
     *
     * @param sufLength
     * @return
     */
    private String getUIDByRandom(int sufLength) {
        if (sufLength < 2 || sufLength > 8) {
            sufLength = ranLen;
        }
        //获取进程及线程号
        String PTID = PTNum();

        //获取指定长度随机数
        int rannum = random(sufLength);

        //获取时间
        SimpleDateFormat sdf = LoanassistConstants.sdf_time1;
        String date = sdf.format(new Date());

        if (log.isDebugEnabled()) {
            log.debug("时间:" + date + "+ PTID:" + PTID + "+ random:" + rannum + " = UID：" + date + PTID + rannum);
        }
        return date + PTID + rannum;
    }

    /**
     * redis自增
     *
     * @param key
     * @param sufLength 自增id
     * @return
     */
//    private String incrId(String key, int sufLength) {
//        String ranNum = "";
//        //定义随机基数
//        StringBuilder strBur1 = new StringBuilder();
//        strBur1.append("1");
//        StringBuilder strBur2 = new StringBuilder();
//        strBur2.append("9");
//        for (int i = 0; i < sufLength - 1; i++) {
//            strBur1.append("0");
//            strBur2.append("9");
//        }
//        //redis自增
//        Long incr = redisTemplate.opsForValue().increment(key, 1L);
//        if (incr == 1
//                || incr >= Integer.valueOf(strBur2.toString())
//                || String.valueOf(incr).length() != sufLength) {
//            redisTemplate.opsForValue().set(key, strBur1.toString());
//            ranNum = strBur1.toString();
//        } else {
//            ranNum = String.valueOf(incr);
//        }
//        return ranNum;
//    }

    /**
     * 获取指定长度的随机数
     *
     * @param randomLength
     * @return
     */
    private int random(int randomLength) {
        //定义随机基数
        StringBuilder strBur1 = new StringBuilder();
        strBur1.append("1");
        StringBuilder strBur2 = new StringBuilder();
        strBur2.append("9");
        for (int i = 0; i < randomLength - 1; i++) {
            strBur1.append("0");
            strBur2.append("0");
        }
        Random random = new Random();
        return (int) (random.nextDouble() * (Integer.valueOf(strBur2.toString()))) + Integer.valueOf(strBur1.toString());
    }

    /**
     * 获取进程及线程号
     *
     * @return
     */
    private String PTNum() {
        //获取进程号并截取ptLength位数
        String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        pid = "0000" + pid;
        pid = pid.substring(pid.length() - ptLen, pid.length());

        //获取线程号并截取ptLength位数
        long threadId = Thread.currentThread().getId();
        String thId = "0000" + threadId;
        thId = thId.substring(thId.length() - ptLen, thId.length());

        return pid + thId;
    }


    public static String toConceal(String value) {
        if (null == value || "".equals(value)) {
            return value;
        }
        int len = value.length();
        int pamaone = len / 2;
        int pamatwo = pamaone - 1;
        int pamathree = len % 2;
        StringBuilder stringBuilder = new StringBuilder();
        if (len <= 2) {
            if (pamathree == 1) {
                return SYMBOL;
            }
            stringBuilder.append(SYMBOL);
            stringBuilder.append(value.charAt(len - 1));
        } else {
            if (pamatwo <= 0) {
                stringBuilder.append(value.substring(0, 1));
                stringBuilder.append(SYMBOL);
                stringBuilder.append(value.substring(len - 1, len));

            } else if (pamatwo >= SIZE / 2 && SIZE + 1 != len) {
                int pamafive = (len - SIZE) / 2;
                stringBuilder.append(value.substring(0, pamafive));
                for (int i = 0; i < SIZE; i++) {
                    stringBuilder.append(SYMBOL);
                }
                stringBuilder.append(value.substring(len - (pamafive + 1), len));
            } else {
                int pamafour = len - 2;
                stringBuilder.append(value.substring(0, 1));
                for (int i = 0; i < pamafour; i++) {
                    stringBuilder.append(SYMBOL);
                }
                stringBuilder.append(value.substring(len - 1, len));
            }
        }
        return stringBuilder.toString();

    }

}
